#include "widget.h"
#include "ui_widget.h"
#include<QGraphicsDropShadowEffect>
#include<QListWidget>
#include<QMessageBox>
#include<QSqlQuery>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    InitUi();
    // 初始化数据库
     initSQLite();
     // 加载数据库歌曲⽂件
      initMusicList();
    // 初始化播放器
    initPlayer();

    connectSignalAndSlot();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::InitUi()
{
    lrcPage = new LrcPage(this);
    lrcPage->setGeometry(0,0,this->width(),this->height());
    lrcPage->hide();

    vt->hide();
    this->setWindowFlag(Qt::FramelessWindowHint);
    this->setAttribute(Qt::WA_TranslucentBackground);
    QGraphicsDropShadowEffect* shadowEffect=new QGraphicsDropShadowEffect(this);
    shadowEffect->setOffset(0,0);
    shadowEffect->setColor("#000000");
    shadowEffect->setBlurRadius(20);
    this->setGraphicsEffect(shadowEffect);


    // 设置BodyLeft中6个btForm的信息
    ui->Rec->seticon(":/images/rec.png", "推荐", 1);
    ui->music->seticon(":/images/music.png", "音乐馆", 2);
    ui->audio->seticon(":/images/radio.png", "电台", 3);
    ui->like->seticon(":/images/like.png", "我喜欢", 4);
    ui->local->seticon(":/images/local.png", "本地下载", 5);
    ui->recent->seticon(":/images/recent.png", "最近播放", 6);

    // 本地下载BtForm动画默认显⽰
    ui->local->showAnimal();
    ui->stackedWidget->setCurrentIndex(4);
    currentPage = ui->localPage;
    srand(time(NULL));
    ui->recMusicBox->initRecBoxUi(randomPiction(),1);
    ui->supplyMuscBox->initRecBoxUi(randomPiction(),2);

    ui->likePage->setSign("我喜欢");
    ui->likePage->setMidImg(":/images/localbg.png");
    ui->localPage->setCommonPageUI("本地音乐", ":/images/localbg.png");
    ui->recentPage->setCommonPageUI("最近播放", ":/images/recentbg.png");
    // 设置静⾳
    connect(vt, &VolumeTool::setSilence, this,
            &Widget::setMusicSilence);

}

void Widget::initSQLite()
{
    // 1. 创建数据库连接
    sqlite = QSqlDatabase::addDatabase("QSQLITE");
    // 2. 设置数据库名称
    sqlite.setDatabaseName("QQMusic.db");
    // 3. 打开数据库
    if(!sqlite.open())
    {
        QMessageBox::critical(this, "打开QQMusicDB失败",
                              sqlite.lastError().text());
        return;
    }
    qDebug()<<"SQLite连接成功，并创建 [QQMusic.db] 数据库!!!";
    // 4. 创建数据库表
    QString sql = ("CREATE TABLE IF NOT EXISTS musicInfo(\
                   id INTEGER PRIMARY KEY AUTOINCREMENT,\
                   musicId varchar(200) UNIQUE,\
                   musicName varchar(50),\
                   musicSinger varchar(50),\
                   albumName varchar(50),\
                   duration BIGINT,\
                   musicUrl varchar(256),\
                   isLike INTEGER,\
                   isHistory INTEGER)"
            );
    QSqlQuery query;
    if(!query.exec(sql))
    {
        return;
    }
    qDebug()<<"创建 [musicInfo] 表成功!!!";
}
void Widget::connectSignalAndSlot()
{
    // ⾃定义的btFrom按钮点击信号，当btForm点击后，设置对应的堆叠窗⼝
    connect(ui->Rec, &btform::click, this, &Widget::onBtFormClick);
    connect(ui->music, &btform::click, this, &Widget::onBtFormClick);
    connect(ui->audio, &btform::click, this, &Widget::onBtFormClick);
    connect(ui->like, &btform::click, this, &Widget::onBtFormClick);
    connect(ui->local, &btform::click, this, &Widget::onBtFormClick);
    connect(ui->recent, &btform::click, this, &Widget::onBtFormClick);

    // qDebug()<<"initalLike";
    connect(ui->likePage,&CommonPage::ResetLike,this,&Widget::RenewLikeFromMusicId);
    connect(ui->localPage,&CommonPage::ResetLike,this,&Widget::RenewLikeFromMusicId);
    connect(ui->recentPage,&CommonPage::ResetLike,this,&Widget::RenewLikeFromMusicId);

    // 关联播放所有的信号和槽函数
    connect(ui->likePage, &CommonPage::playAll, this, &Widget::onPlayAll);
    connect(ui->localPage, &CommonPage::playAll, this, &Widget::onPlayAll);
    connect(ui->recentPage, &CommonPage::playAll, this, &Widget::onPlayAll);

    connect(ui->likePage, &CommonPage::playMusicByIndex, this,
            &Widget::playMusicByIndex);
    connect(ui->localPage, &CommonPage::playMusicByIndex, this,
            &Widget::playMusicByIndex);
    connect(ui->recentPage, &CommonPage::playMusicByIndex, this,
            &Widget::playMusicByIndex);

    // 设置静⾳
    connect(vt, &VolumeTool::setSilence, this,
            &Widget::setMusicSilence);
    // 设置⾳量⼤⼩
    connect(vt, &VolumeTool::setMusicVolume, this,
            &Widget::setPlayerVolume);
    // 进度条拖拽
    connect(ui->processBar, &MusicBar::setMusicSliderPosition, this,
            &Widget::onMusicSliderChanged);



}

void Widget::onBtFormClick(int id)
{
    // 1.获取当前⻚⾯所有btFrom按钮类型的对象
    QList<btform*> buttonList = this->findChildren<btform*>();
    // 2.遍历所有对象, 如果不是当前id的按钮,则把之前设置的背景颜⾊清除掉
    foreach (btform* btitem, buttonList)
    {
        if (id != btitem->getId())
        {
            btitem->clearBg();
        }
    }

    // 设置当前栈空间显⽰⻚⾯
    ui->stackedWidget->setCurrentIndex(id - 1);
    // 点击btForm时，窗⼝不能拖拽
    isDrag = false;
}


void Widget::mouseMoveEvent(QMouseEvent *ev)
{
    if(Qt::LeftButton==ev->buttons()&& isDrag)
    {
        move(ev->globalPos()-dragPosition);
    }
    QWidget::mouseMoveEvent(ev);
}

void Widget::mousePressEvent(QMouseEvent *ev)
{
    if(Qt::LeftButton==ev->button())
    {
        isDrag=true;
        dragPosition=ev->globalPos()-geometry().topLeft();
    }
    QWidget::mousePressEvent(ev);
}

void Widget::RenewLikeFromMusicId(bool like, QString MusicId)
{
    auto it=musicList.findMusicById(MusicId);
    if(it!=musicList.end())
    {
        it->setIsLike(like);
        qDebug()<<"widget:"<<like;
    }
    ui->localPage->reFresh(musicList);
    ui->likePage->reFresh(musicList);
    ui->recentPage->reFresh(musicList);
}

void Widget::onPlayStateChanged()
{
    if(player->state() == QMediaPlayer::PlayingState)
    {
        // 播放状态
        ui->play->setIcon(QIcon(":/images/play_on.png"));
    }
    else
    {
        // 暂停状态
        ui->play->setIcon(QIcon(":/images/play3.png"));
    }
}

void Widget::onPlaybackModeChanged(QMediaPlaylist::PlaybackMode playbackMode)
{
    if(playbackMode == QMediaPlaylist::Loop)
    {
        ui->playMode->setIcon(QIcon(":/images/list_play.png"));
    }
    else if(playbackMode == QMediaPlaylist::Random)
    {
        ui->playMode->setIcon(QIcon(":/images/shuffle_2.png"));
    }
    else if(playbackMode == QMediaPlaylist::CurrentItemInLoop)
    {
        ui->playMode->setIcon(QIcon(":/images/single_play.png"));
    }
    else
    {
        qDebug()<<"暂不⽀持该模式";
    }
}

void Widget::onPlayAll(PageType pageType)
{
    CommonPage* page = nullptr;
    switch(pageType)
    {
    case PageType::LIKE_PAGE:
        page = ui->likePage;
        break;
    case PageType::LOCAL_PAGE:
        page = ui->localPage;
        break;
    case PageType::HISTORY_PAGE:
        page = ui->recentPage;
        break;
    default:
        qDebug()<<"扩展";
    }
    // 从当前页⾯的零号位置开始播放
    playAllOfCommonPage(page,0);
}

void Widget::playAllOfCommonPage(CommonPage *commonPage, int index)
{
    // 播放page所在页⾯的⾳乐
    // 将播放列表先清空，否则⽆法播放当前CommonPage页⾯的歌曲
    // 另外：该页⾯⾳乐不⼀定就在播放列表中，因此需要先将该页⾯⾳乐添加到播放列表
    currentPage = commonPage;

    // 将当前页⾯歌曲添加到播放列表
    commonPage->addMusicToPlayer(musicList, playList);
    // 设置当前播放列表的索引
    playList->setCurrentIndex(index);
    // 播放
    player->play();
}

void Widget::onCurrentIndexChanged(int index)
{
    // ⾳乐的id都在commonPage中的musicListOfPage中存储着
    const QString& musicId = currentPage->getMusicIdByIndex(index);
    // 有了MusicId就可以再musicList中找到该⾳乐
    auto it= musicList.findMusicById(musicId);
    if(it != musicList.end())
    {
        // 将该⾳乐设置为历史播放记录
        it->setIsHistory(true);
    }
    ui->recentPage->reFresh(musicList);

}

void Widget::playMusicByIndex(CommonPage *page, int index)
{
    playAllOfCommonPage(page, index);
}

void Widget::setPlayerVolume(int volume)
{
    player->setVolume(volume);
}



void Widget::initPlayer()
{
    // 创建播放器
    player = new QMediaPlayer(this);
    // 创建播放列表
    playList = new QMediaPlaylist(this);
    playList->setPlaybackMode(QMediaPlaylist::Loop);
    player->setPlaylist(playList);  //设置player的播放列表
    player->setVolume(45);

    // QMediaPlayer信号和槽函数关联
    // 播放状态改变时：暂停和播放之间切换
    connect(player, &QMediaPlayer::stateChanged, this,
            &Widget::onPlayStateChanged);
    // 播放列表的模式放⽣改变时的信号槽关联
    connect(playList, &QMediaPlaylist::playbackModeChanged, this,
            &Widget::onPlaybackModeChanged);
    // 播放列表项发⽣改变，此时将播放⾳乐收藏到历史记录中
    connect(playList, &QMediaPlaylist::currentIndexChanged, this,
            &Widget::onCurrentIndexChanged);
    // 媒体持续时⻓更新，即：⾳乐切换，时⻓更新，界⾯上时间也要更新
    connect(player, &QMediaPlayer::durationChanged, this,
            &Widget::onDurationChanged);
    // 播放位置发⽣改变，即已经播放时间更新
    connect(player, &QMediaPlayer::positionChanged, this,
            &Widget::onPositionChanged);
    connect(playList,&QMediaPlaylist::currentIndexChanged,[=](int index){
        curPlayMusicIndex=index;
    });
    connect(player,&QMediaPlayer::metaDataAvailableChanged,this,&Widget::onMetaDataAvailableChangedChanged);
}

void Widget::initMusicList()
{
    // 1. 从数据库读取歌曲信息
     musicList.readFromDB();
     // 2. 更新CommonPage⻚⾯
     // 设置CommonPage的信息
     ui->likePage->setMusicListType(PageType::LIKE_PAGE);
     ui->likePage->reFresh(musicList);

     ui->localPage->setMusicListType(PageType::LOCAL_PAGE);
     ui->localPage->reFresh(musicList);

     ui->recentPage->setMusicListType(PageType::HISTORY_PAGE);
     ui->recentPage->reFresh(musicList);
}

void Widget::onMusicSliderChanged(float value)
{
    // 1. 计算当前seek位置的时⻓
    qint64 duration = (qint64)(player->duration() * value);
    // 2. 转换为百分制，设置当前时间
    ui->currentTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10,
                                                  QChar('0'))
                             .arg(duration/1000%60, 2, 10,
                                  QChar('0')));
    // 3. 设置当前播放位置
    player->setPosition(duration);
}

void Widget::onMetaDataAvailableChangedChanged(bool available)
{
    // 播放源改变
    qDebug()<<"歌曲切换";
    // 1. 从player播放歌曲的元数据中获取歌曲信息
    QString singer = player->metaData("Author").toStringList().join(",");
    QString musicName = player->metaData("Title").toString();

    auto it = musicList.findMusicById(currentPage->getMusicIdByIndex(curPlayMusicIndex));
    if(it != musicList.end())
    {
        musicName = it->getMusicName();
        singer = it->getMusicSinger();
    }

    // 2. 设置歌手、歌曲名称、专辑名称

    ui->musicName->setText(musicName);
    ui->musicSinger->setText(singer);
    // 3. 获取封面图片
    QVariant coverImage = player->metaData("ThumbnailImage");
    if(coverImage.isValid())
    {
        // 获取封面图片成功
        QImage image = coverImage.value<QImage>();
        // 设置封面图片
        ui->musicCover->setPixmap(QPixmap::fromImage(image));
        // 缩放填充到整个Label
        ui->musicCover->setScaledContents(true);
    }
    else
    {
        // 设置默认图片修改
        qDebug()<<"歌曲没有封面图片";
        ui->musicCover->setPixmap(QPixmap(":/images/recentbg.png"));
        // 缩放填充到整个Label
        ui->musicCover->setScaledContents(true);
    }
    QString lrcPath=it->getLrcFilePath();
    lrcPage->parseLrc(lrcPath);
    
}

void Widget::onPositionChanged(qint64 duration)
{
    ui->currentTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10,QChar('0')).arg(duration/1000%60,2,10,QChar('0')));

    // 界⾯上的进度条也需要同步修改
    ui->processBar->setStep((float)duration / (float)player->duration());

    // 3. 同步lrc歌词
    if(playList->currentIndex() >= 0)
    {
        lrcPage->showLrcWord(duration);
    }
}


QJsonArray Widget::randomPiction()
{
    // 推荐⽂本 + 推荐图⽚路径
    QVector<QString> vecImageName;
    vecImageName<<"001.png"<<"003.png"<<"004.png"<<"005.png"<<"006.png"
               <<"007.png"
              <<"008.png"<<"009.png"<<"010.png"<<"011.png"<<"012.png"
             <<"013.png"
            <<"014.png"<<"015.png"<<"016.png"<<"017.png"<<"018.png"
           <<"019.png"
          <<"020.png"<<"021.png"<<"022.png"<<"023.png"<<"024.png"
         <<"025.png"
        <<"026.png"<<"027.png"<<"028.png"<<"029.png"<<"030.png"
       <<"031.png"
      <<"032.png"<<"033.png"<<"034.png"<<"035.png"<<"036.png"
     <<"037.png"
    <<"038.png"<<"039.png"<<"040.png";
    std::random_shuffle(vecImageName.begin(), vecImageName.end());
    // 001.png
    // path: ":/images/rec/"+vecImageName[i];
    // text: "推荐-001"
    QJsonArray objArray;
    for(int i = 0; i < vecImageName.size(); ++i)
    {
        QJsonObject obj;
        obj.insert("path", ":/images/rec/"+vecImageName[i]);
        // arg(i, 3, 10, QCchar('0'))
        // i：要放⼊%1位置的数据
        // 3: 三位数
        // 10：表⽰⼗进制数
        // QChar('0')：数字不够三位，前⾯⽤字符'0'填充
        QString strText = QString("推荐-%1").arg(i, 3, 10, QChar('0'));
        obj.insert("text", strText);
        objArray.append(obj);
    }
    return objArray;
}

QJsonArray Widget::RandomPicture()
{

}

void Widget::onDurationChanged(qint64 duration)
{
    ui->totalTime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10,QChar('0')).arg(duration/1000%60,2,10,QChar('0')));
}

void Widget::setMusicSilence(bool isMuted)
{
    player->setMuted(isMuted);
}

void Widget::on_quit_clicked()
{
    // 更新数据库
     musicList.writeToDB();
     // 关闭数据库连接
      sqlite.close();
    this->close();
}


void Widget::on_volume_clicked()
{
    QPoint po=ui->volume->mapToGlobal(QPoint(0,0));
    QPoint po_volumetool=po-QPoint(vt->width()/3,vt->height());
    vt->move(po_volumetool);
    vt->show();

}


void Widget::on_addLocal_clicked()
{
    QFileDialog fileDialog(this);
    // 6. 显⽰对话框，并接收返回值
    // 模态对话框, exec内部是死循环处理
    // 设置一次多开多个
    fileDialog.setFileMode(QFileDialog::ExistingFiles);
    // 通过文件的MIME类型来过滤
    QStringList mimeTypeFilters;
    mimeTypeFilters << "application/octet-stream";    // All(*)
    fileDialog.setMimeTypeFilters(mimeTypeFilters);
    fileDialog.setDirectory(QDir::currentPath());
    if(fileDialog.exec() == QFileDialog::Accepted)
    {
        // 切换到本地⾳乐界⾯，因为加载完的⾳乐需要在本地⾳乐界⾯显⽰
        ui->stackedWidget->setCurrentIndex(4);
        // 获取对话框的返回值
        QList<QUrl> urls = fileDialog.selectedUrls();
        // 注意：后序需要将⾳乐信息添加到数据库，否则每次打开是都需要添加⾳乐太⿇烦了
        musicList.addMusicByUrl(urls);
        // 更新到本地⾳乐列表
        ui->localPage->reFresh(musicList);

    }
}


void Widget::on_play_clicked()
{
    if(player->state() == QMediaPlayer::PlayingState){
        // 如果是歌曲正在播放中，按下播放键，此时应该暂停播放
        player->pause();
    }
    else if(player->state() == QMediaPlayer::PausedState)
    {
        // 如果是暂停状态，按下播放键，继续开始播放
        player->play();
    }
    else if(player->state() == QMediaPlayer::StoppedState)
    {
        player->play();
    }
}


void Widget::on_playPrev_clicked()
{
    playList->previous();
}


void Widget::on_playNext_clicked()
{
    playList->next();
}


void Widget::on_playMode_clicked()
{
    // 播放模式是针对播放列表的
    // 播放模式⽀持：循环播放、随机播放、单曲循环三种模式
    if(playList->playbackMode() == QMediaPlaylist::Loop)
    {
        // 列表循环
        ui->playMode->setToolTip("随机播放");
        playList->setPlaybackMode(QMediaPlaylist::Random);
    }
    else if(playList->playbackMode() == QMediaPlaylist::Random)
    {
        // 随机播放
        ui->playMode->setToolTip("单曲循环");
        playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
    }
    else if(playList->playbackMode() == QMediaPlaylist::CurrentItemInLoop)
    {
        ui->playMode->setToolTip("列表循环");
    }
    else
    {
        qDebug()<<"播放模式错误";
    }
}


void Widget::on_pushButton_3_clicked()
{
    close();
}

void Widget::on_lrcWord_clicked()
{
    lrcPage->show();
}
